package com.arithmeticEveryDay.leetCode;

import java.util.Scanner;

/*

一条包含字母 A-Z 的消息通过以下映射进行了 编码 ：

'A' -> "1"
'B' -> "2"
...
'Z' -> "26"
要 解码 已编码的消息，所有数字必须基于上述映射的方法，反向映射回字母（可能有多种方法）。例如，"11106" 可以映射为：

"AAJF" ，将消息分组为 (1 1 10 6)
"KJF" ，将消息分组为 (11 10 6)
注意，消息不能分组为  (1 11 06) ，因为 "06" 不能映射为 "F" ，这是由于 "6" 和 "06" 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ，请计算并返回 解码 方法的 总数 。

题目数据保证答案肯定是一个 32 位 的整数。

 

示例 1：

输入：s = "12"
输出：2
解释：它可以解码为 "AB"（1 2）或者 "L"（12）。
示例 2：

输入：s = "226"
输出：3
解释：它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
示例 3：

输入：s = "06"
输出：0
解释："06" 无法映射到 "F" ，因为存在前导零（"6" 和 "06" 并不等价）。
 

提示：

1 <= s.length <= 100
s 只包含数字，并且可能包含前导零。


1  ——1
11  ——2
1 1
11
111   ——3
1 1 1
1 11
11 1
1111  ——5
1 1 1 1
1 1 11
1 11 1
11 1 1
11 11
11111  ——8
1 1 1 1 1
1 1 1 11
1 1 11 1
1 11 1 1
1 11 11
11 1 1 1
11 1 11
11 11 1
1   ——1
10  ——1
1010  ——1
101010 ——1
110  ——1
1110   ——2
1 1 10
11 10
11110   ——3
1 1 1 10
1 11 10
11 1 10
111101  ——3
1 1 1 10 1
1 11 10 1
11 1 10 1
1111011   ——6
1 1 1 10 1 1
1 1 1 10 11
1 11 10 1 1
1 11 10 11
11 1 10 1 1
11 1 10 11




1、__的情况，其中_为非零数字
其中<=26的情况：
111011
1 1 10 1 1
11 10 1 1
1 1 10 11
11 10 11
= 1110(2) + 11101(2)
101011
= 1010(1) + 10101(1)
总结为dp[i] = dp[i-1] + dp[i-2]
>26：
1027
= 102(1)
1127
= 112(1)
总结为dp[i] = dp[i-1]

2、10或20
111010
= 1110(2) = 11101(2)
注意这个110
= 1(1) != 11(2)
总结为dp[i] = dp[i-2]

3、0_的情况，其中_为非零数字
11101
= 1110(2)
111027
= 11102(2)


 */
public class Solution91 {
    
    public int numDecodings(String s) {
        // deCodeNum[i]表示s从0到i索引的解码数量
        int[] deCodeNum = new int[s.length()];
        int n = deCodeNum.length;
        char ch0 = s.charAt(0);
        if (ch0 == '0') {
            return 0;
        }
        if (n == 1) {
            deCodeNum[0] = 1;
            return deCodeNum[0];
        }
        deCodeNum[0] = 1;
        char ch1 = s.charAt(1);
        if (ch1 == '0') {
            deCodeNum[1] = deCodeNum[0];
            if (ch0 > '2' && ch0 <= '9') {
                return 0;
            }
        } else if (ch1 > '0' && ch1 <= '9') {
            int value1 = (ch0 - '0') * 10 + ch1 - '0';
            if (value1 <= 26) {
                deCodeNum[1] = 2;
            } else {
                deCodeNum[1] = deCodeNum[0];
            }
        }
        for (int i = 2; i < n; i++) {
            char chI = s.charAt(i);
            char ch_Iminus1 = s.charAt(i-1);
            if (chI == '0') {
                // 10或20
                if (ch_Iminus1 == '1' || ch_Iminus1 == '2') {
                    deCodeNum[i] = deCodeNum[i-2];
                } else {
                    return 0;
                }
            } else if (chI > '0' && chI <= '9') {
                // 0_，其中_为非零数字
                if (ch_Iminus1 == '0') {
                    deCodeNum[i] = deCodeNum[i-1];
                // __的情况，其中_为非零数字
                } else if (ch_Iminus1 > '0' && ch_Iminus1 <= '9') {
                    int value = (ch_Iminus1 - '0') * 10 + chI - '0';
                    if (value <= 26) {
                        deCodeNum[i] = deCodeNum[i-1] + deCodeNum[i-2];
                    } else {
                        deCodeNum[i] = deCodeNum[i-1];
                    }
                }
            } else {
                return 0;
            }
        }
        return deCodeNum[n-1];
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.next();
        Solution91 s = new Solution91();
        System.out.println(s.numDecodings(str));
    }

}
